/* eslint-disable comma-dangle */
/* eslint-disable arrow-parens */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable newline-after-var */
/* eslint-disable semi */
/* eslint-disable quotes */
import { mergeAttributes, Node } from "@tiptap/core";

export interface TemplateVariableOptions {
  HTMLAttributes: Record<string, any>;
}

export const TemplateVariable = Node.create<TemplateVariableOptions>({
  name: "templateVariable",
  group: "inline",
  inline: true,
  atom: true,
  content: "text*",
  selectable: true,
  priority: 1000,

  addOptions() {
    return {
      HTMLAttributes: {
        class: "template-variable",
      },
    };
  },

  addAttributes() {
    return {
      inputValue: {
        default: "",
      },
      placeholder: {
        default: "placeholder",
      },
      defaultValue: {
        default: "",
      },
    };
  },

  renderHTML({ node, HTMLAttributes }) {
    return [
      "input",
      mergeAttributes(
        {
          class: "template-variable",
          inputValue: node.attrs.inputValue,
          placeholder: node.attrs.placeholder || "变量内容2",
        },
        { ...HTMLAttributes }
      ),
    ];
  },

  addNodeView() {
    return ({ node, editor, getPos }) => {
      function adjustWidth() {
        const tmp = document.createElement("span");

        tmp.style.visibility = "hidden";
        tmp.style.position = "absolute";
        tmp.style.whiteSpace = "pre";
        tmp.style.font = window.getComputedStyle(dom).font;

        const valueText = dom.value || "";
        const placeholderText = dom.getAttribute("placeholder") || "";

        // 优先使用 dom.value，如果不存在则使用 placeholder
        tmp.textContent = valueText || placeholderText;

        document.body.appendChild(tmp);
        const width = tmp.getBoundingClientRect().width + 16;
        document.body.removeChild(tmp);

        requestAnimationFrame(() => {
          dom.style.width = `${Math.max(width, 60)}px`;
        });
      }

      const dom = document.createElement("input");
      dom.setAttribute("data-template-variable", "true");
      dom.classList.add("template-variable");
      dom.setAttribute("type", "text");
      dom.setAttribute("tabindex", "0");

      // 不设置默认value，只设置data-default-content用于内部逻辑
      const initialValue = node.attrs.inputValue || "";
      const defaultValue = node.attrs.defaultValue || "";
      dom.setAttribute("data-default-content", initialValue);
      dom.setAttribute("placeholder", node.attrs.placeholder);


      // 只有defaultValue存在时才设置为input的显示值
      if (defaultValue && !initialValue) {
        dom.value = defaultValue;
        adjustWidth();
      } else if (initialValue) {
        dom.value = initialValue;
        adjustWidth();
      }
      dom.style.outline = "none";
      dom.style.border = "none";
      dom.style.backgroundColor = "transparent";
      dom.style.padding = "0 4px";
      dom.style.minWidth = "2em";
      dom.style.textAlign = "left";
      dom.style.transition = "background-color 0.2s ease, box-shadow 0.2s ease";

      adjustWidth();

      let isEditing = false;

      // 监听编辑器选择变化，当节点被选中时自动聚焦
      const checkSelection = () => {
        if (typeof getPos === "function" && editor) {
          const pos = getPos();
          if (pos !== undefined && pos !== false && pos >= 0) {
            const { from, to } = editor.state.selection;
            // 检查当前节点是否在选择范围内
            if (from <= pos && to >= pos + node.nodeSize) {
              // 延迟聚焦，确保DOM已更新
              setTimeout(() => {
                if (!isEditing && document.activeElement !== dom) {
                  dom.focus();
                  // 根据光标移动方向设置位置
                  const lastSelection = editor.state.selection;
                  const prevPos = lastSelection.$from.pos;

                  if (prevPos < pos) {
                    // 从左边移入，聚焦到开头
                    dom.setSelectionRange(0, 0);
                  } else {
                    // 从右边移入，聚焦到末尾
                    dom.setSelectionRange(dom.value.length, dom.value.length);
                  }
                }
              }, 10);
            }
          }
        }
      };

      // 监听编辑器选择变化
      editor.on("selectionUpdate", checkSelection);

      // 额外监听键盘事件，处理移入节点的情况
      const handleGlobalKeydown = (event) => {
        if (
          event.key === "ArrowLeft" ||
          event.key === "ArrowRight" ||
          event.key === "ArrowUp" ||
          event.key === "ArrowDown"
        ) {
          setTimeout(() => {
            if (typeof getPos === "function" && editor) {
              const pos = getPos();
              if (pos !== undefined && pos !== false && pos >= 0) {
                const { from, to } = editor.state.selection;
                // 检查光标是否刚好移入当前节点
                if (from === pos && to === pos + node.nodeSize) {
                  if (!isEditing && document.activeElement !== dom) {
                    dom.focus();
                    if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
                      // 从右边或下方移入，聚焦到末尾
                      dom.setSelectionRange(dom.value.length, dom.value.length);
                    } else {
                      // 从左边或上方移入，聚焦到开头
                      dom.setSelectionRange(0, 0);
                    }
                  }
                }
              }
            }
          }, 0);
        }

        // 处理普通字符输入，防止覆盖节点
        if (typeof getPos === "function" && editor) {
          const pos = getPos();
          if (pos !== undefined && pos !== false && pos >= 0) {
            const { from, to } = editor.state.selection;
            // 检查当前节点是否被选中
            if (from === pos && to === pos + node.nodeSize) {
              // 如果是普通字符输入（字母、数字、空格等）
              if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
                event.preventDefault();
                event.stopPropagation();

                // 聚焦到 input 并插入字符
                if (!isEditing && document.activeElement !== dom) {
                  dom.focus();
                  dom.setSelectionRange(0, 0);
                }

                // 在当前光标位置插入字符
                const currentPos = dom.selectionStart || 0;
                const currentValue = dom.value;
                const newValue = currentValue.slice(0, currentPos) + event.key + currentValue.slice(currentPos);
                dom.value = newValue;
                dom.setSelectionRange(currentPos + 1, currentPos + 1);

                // 触发 input 事件以更新宽度和对齐
                const inputEvent = new Event('input', { bubbles: true });
                dom.dispatchEvent(inputEvent);

                return;
              }
            }
          }
        }
      };

      // 添加全局键盘监听
      document.addEventListener("keydown", handleGlobalKeydown);

      dom.addEventListener("focus", () => {
        isEditing = true;
        dom.classList.add("editing-template-var");
      });

      dom.addEventListener("input", (event) => {
        event.stopPropagation();
        adjustWidth();
        dom.style.textAlign = dom.value ? "center" : "left";

        // 实时保存内容变化
        updateContent();
      });

      dom.addEventListener("blur", () => {
        setTimeout(() => {
          if (isEditing) {
            isEditing = false;
            dom.classList.remove("editing-template-var");
            updateContent();
          }
        }, 100);
      });

      function updateContent() {
        const newContent = dom.value || "";
        const originalContent = dom.getAttribute("data-default-content") || "";

        if (originalContent === newContent) return;

        if (typeof getPos === "function") {
          try {
            const pos = getPos();

            if (pos === undefined || pos === false || pos < 0) return;

            const transaction = editor.state.tr;

            try {
              const curNode = transaction.doc.nodeAt(pos);
              if (!curNode || curNode.type.name !== "templateVariable") return;
              transaction.setNodeMarkup(pos, undefined, {
                ...curNode.attrs,
                inputValue: newContent,
              });
              editor.view.dispatch(transaction);
            } catch (error) {
              // eslint-disable-next-line no-console
              console.error("更新模板变量过程中发生错误:", error);
            }
          } catch (error) {
            // eslint-disable-next-line no-console
            console.error("获取节点位置时发生错误:", error);
          }
        }
      }

      dom.addEventListener("keydown", (event) => {
        // 复制节点（Shift+Enter，且input聚焦且value为空）
        if (event.key === "Enter" && event.shiftKey) {
          event.preventDefault();

          // 新增：如果输入框有值且光标不在首尾，则分割节点
          if (document.activeElement === dom && dom.value) {
            const caretPos = dom.selectionStart || 0;
            const valueLen = dom.value.length;

            // 光标在开头位置，在前面插入空白节点 光标在中间位置，需要分割 光标在末尾位置，在后面插入空白节点
            if (caretPos === 0 || (caretPos > 0 && caretPos < valueLen) || caretPos === valueLen) {
              if (typeof getPos === "function" && editor) {
                const { state, view } = editor;
                const pos = getPos();
                const nodeType = state.schema.nodes.templateVariable;

                if (nodeType) {
                  const tr = state.tr;

                  // 获取光标前后的内容
                  const beforeText = dom.value.substring(0, caretPos);
                  const afterText = dom.value.substring(caretPos);

                  // 直接修改当前节点为 beforeText
                  const currentNode = tr.doc.nodeAt(pos);
                  if (currentNode && currentNode.type.name === "templateVariable") {
                    tr.setNodeMarkup(pos, undefined, {
                      ...currentNode.attrs,
                      inputValue: beforeText,
                    });

                    // 立即更新当前 DOM 的值
                    dom.value = beforeText;
                    dom.setAttribute("data-default-content", beforeText);
                    adjustWidth();
                  }

                  // 创建后节点
                  const afterNode = nodeType.create({
                    inputValue: "",
                    placeholder: node.attrs.placeholder || "变量内容",
                    defaultValue: afterText,
                  });

                  // 创建包含afterNode的新段落
                  const paragraphType = state.schema.nodes.paragraph;
                  const afterParagraph = paragraphType.create(null, afterNode);

                  // 在当前节点后插入新段落
                  const insertPos = pos + node.nodeSize;
                  tr.insert(insertPos, afterParagraph);

                  // 设置选择到后节点
                  const afterNodePos = insertPos + 1;
                  tr.setSelection(state.selection.constructor.near(tr.doc.resolve(afterNodePos)));

                  view.dispatch(tr);

                  // 强制重新渲染DOM并聚焦到后节点
                  setTimeout(() => {
                    view.updateState(view.state);

                    const pmEditor = view.dom as HTMLElement;
                    const inputs = pmEditor.querySelectorAll("input.template-variable");
                    let targetInput: HTMLInputElement | null = null;

                    // 通过内容匹配找到后节点（空节点通过placeholder匹配）
                    inputs.forEach((input) => {
                      if (afterText) {
                        // 有内容的情况
                        if (input.value === afterText && input !== dom) {
                          targetInput = input as HTMLInputElement;
                        }
                      } else {
                        // 空节点的情况
                        if (
                          !input.value &&
                          input.placeholder === (node.attrs.placeholder || "变量内容") &&
                          input !== dom
                        ) {
                          targetInput = input as HTMLInputElement;
                        }
                      }
                    });

                    if (targetInput) {
                      targetInput.focus();
                      targetInput.setSelectionRange(0, 0);
                    } else {
                      view.focus();
                    }
                  }, 10);

                  dom.blur();
                }
              }
              return;
            }
          }

          // 原有逻辑：输入框为空时复制节点
          if (document.activeElement === dom && !dom.value) {
            if (typeof getPos === "function" && editor) {
              const { state, view } = editor;

              const pos = getPos();
              const nodeType = state.schema.nodes.templateVariable;
              if (nodeType) {
                const paragraphType = state.schema.nodes.paragraph;
                const tr = state.tr;
                const insertPos = pos + node.nodeSize;
                let currentContent = node.attrs.inputValue;
                if (!currentContent) {
                  currentContent = dom.getAttribute("data-default-content") || "";
                }
                // 同步当前节点内容
                if (typeof getPos === "function") {
                  const curPos = getPos();
                  if (curPos !== undefined && curPos !== false && curPos >= 0) {
                    const curNode = state.doc.nodeAt(curPos);
                    if (
                      curNode &&
                      curNode.type.name === "templateVariable" &&
                      curNode.attrs.inputValue !== currentContent
                    ) {
                      tr.setNodeMarkup(curPos, undefined, {
                        ...curNode.attrs,
                        inputValue: currentContent,
                      });
                    }
                  }
                }
                const newVarNode = nodeType.create({
                  inputValue: currentContent,
                  placeholder: currentContent || node.attrs.placeholder || "变量内容",
                });
                const newParagraph = paragraphType.create(null, newVarNode);
                tr.insert(insertPos, newParagraph);
                const newVarPos = insertPos + 2;
                tr.setSelection(state.selection.constructor.near(tr.doc.resolve(newVarPos)));
                view.dispatch(tr);

                // 直接聚焦到新节点，而不是通过DOM查找
                setTimeout(() => {
                  // 设置选择到新节点并触发自动聚焦
                  const newSelection = state.selection.constructor.near(tr.doc.resolve(newVarPos));
                  view.dispatch(view.state.tr.setSelection(newSelection));

                  // 查找新创建的 input 元素并聚焦
                  const pmEditor = view.dom as HTMLElement;
                  const inputs = pmEditor.querySelectorAll("input.template-variable");
                  let targetInput: HTMLInputElement | null = null;

                  // 查找位置匹配的新 input
                  inputs.forEach((input) => {
                    const inputElement = input as HTMLInputElement;
                    if (inputElement !== dom) {
                      // 通过 DOM 位置判断是否是新创建的节点
                      const inputPos = view.posAtDOM(inputElement, 0);
                      if (inputPos >= newVarPos - 1 && inputPos <= newVarPos + 1) {
                        targetInput = inputElement;
                      }
                    }
                  });

                  if (targetInput) {
                    targetInput.focus();
                    targetInput.setSelectionRange(0, 0);
                  } else {
                    view.focus();
                  }
                }, 10);

                dom.blur();
              }
            }
            return;
          }
        }

        // 上下左右方向键处理
        if (
          event.key === "ArrowLeft" ||
          event.key === "ArrowRight" ||
          event.key === "ArrowUp" ||
          event.key === "ArrowDown"
        ) {
          // 左右键：边界检查
          if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
            const caretPos = dom.selectionStart;
            const valueLen = dom.value.length;
            if (
              (event.key === "ArrowLeft" && caretPos === 0) ||
              (event.key === "ArrowRight" && caretPos === valueLen)
            ) {
              if (typeof getPos === "function" && editor) {
                // 移出前已通过 input 事件实时保存，无需重复保存

                const pos = getPos();
                const { state, view } = editor;
                let targetPos = pos;
                if (event.key === "ArrowRight") {
                  targetPos = pos + node.nodeSize;
                }
                view.dispatch(
                  state.tr.setSelection(
                    state.selection.constructor.near(state.doc.resolve(targetPos))
                  )
                );
                setTimeout(() => {
                  view.focus();
                }, 0);
              }
              isEditing = false;
              dom.blur();
              event.preventDefault();
              return;
            }
          }

          // 上下键：移动到上下行
          if (event.key === "ArrowUp" || event.key === "ArrowDown") {
            if (typeof getPos === "function" && editor) {
              // 移出前已通过 input 事件实时保存，无需重复保存

              const pos = getPos();
              const { state, view } = editor;

              // 使用编辑器的垂直导航
              const direction = event.key === "ArrowUp" ? -1 : 1;
              const $pos = state.doc.resolve(pos);

              // 尝试查找上下行的位置
              let targetPos = pos;
              if (direction === -1) {
                // 向上移动：查找上一行
                const prevLine = view.domAtPos(pos);
                if (prevLine.node && prevLine.node.parentElement) {
                  const rect = prevLine.node.parentElement.getBoundingClientRect();
                  const coords = view.posAtCoords({
                    left: rect.left + rect.width / 2,
                    top: rect.top - 20, // 向上移动一行的高度
                  });
                  if (coords) {
                    targetPos = coords.pos;
                  }
                }
              } else {
                // 向下移动：查找下一行
                const nextLine = view.domAtPos(pos + node.nodeSize);
                if (nextLine.node && nextLine.node.parentElement) {
                  const rect = nextLine.node.parentElement.getBoundingClientRect();
                  const coords = view.posAtCoords({
                    left: rect.left + rect.width / 2,
                    top: rect.bottom + 20, // 向下移动一行的高度
                  });
                  if (coords) {
                    targetPos = coords.pos;
                  }
                }
              }

              view.dispatch(
                state.tr.setSelection(
                  state.selection.constructor.near(state.doc.resolve(targetPos))
                )
              );
              setTimeout(() => {
                view.focus();
              }, 0);
            }
            isEditing = false;
            dom.blur();
            event.preventDefault();
            return;
          }
        }

        // Backspace/Delete 处理
        if (event.key === "Backspace" || event.key === "Delete") {
          const caretPos = dom.selectionStart;
          const valueLen = dom.value.length;
          if (
            (event.key === "Backspace" && caretPos === 0) ||
            (event.key === "Delete" && caretPos === valueLen)
          ) {
            if (typeof getPos === "function" && editor) {
              const pos = getPos();
              const { state, view } = editor;
              let tr = state.tr;
              let targetPos = pos;
              if (event.key === "Backspace") {
                if (pos > 0) {
                  const $before = state.doc.resolve(pos - 1);
                  if (
                    $before.parent.isTextblock &&
                    $before.nodeBefore &&
                    $before.nodeBefore.isText
                  ) {
                    tr = tr.delete(pos - 1, pos);
                    targetPos = pos - 1;
                  } else {
                    targetPos = pos - 1;
                  }
                }
              }
              if (event.key === "Delete") {
                if (pos + node.nodeSize < state.doc.content.size) {
                  const $after = state.doc.resolve(pos + node.nodeSize);
                  if ($after.parent.isTextblock && $after.nodeAfter && $after.nodeAfter.isText) {
                    tr = tr.delete(pos + node.nodeSize, pos + node.nodeSize + 1);
                    targetPos = pos + node.nodeSize;
                  } else {
                    targetPos = pos + node.nodeSize;
                  }
                }
              }
              tr = tr.setSelection(state.selection.constructor.near(tr.doc.resolve(targetPos)));
              view.dispatch(tr);
              setTimeout(() => {
                view.focus();
              }, 0);
            }
            isEditing = false;
            dom.blur();
            event.preventDefault();
            return;
          }
        }

        if (event.key === "Enter") {
          // event.preventDefault();
          // updateContent();
          // dom.blur();
          adjustWidth();
        } else {
          adjustWidth();
        }
      });

      return {
        dom,
        update(updatedNode) {
          if (updatedNode.type !== node.type) return false;
          if (!isEditing) {
            const updatedContent = updatedNode.attrs.inputValue || "";
            const updatedDefaultValue = updatedNode.attrs.defaultValue || "";
            dom.setAttribute("data-default-content", updatedContent);

            // 根据defaultValue决定是否显示值
            if (updatedDefaultValue && !dom.value) {
              dom.value = updatedDefaultValue;
              adjustWidth();
            } else if (updatedContent && !dom.value) {
              // 只在有内容且节点刚创建时设置value（用于分割后的节点）
              dom.value = updatedContent;
              adjustWidth();
            }
            adjustWidth();
          }
          return true;
        },
        destroy() {
          // 清理事件监听器
          editor.off("selectionUpdate", checkSelection);
          document.removeEventListener("keydown", handleGlobalKeydown);
        },
        stopEvent(event) {
          // 增加对普通字符输入的拦截
          if (event.type === "keydown" && event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
            if (typeof getPos === "function" && editor) {
              const pos = getPos();
              if (pos !== undefined && pos !== false && pos >= 0) {
                const { from, to } = editor.state.selection;
                // 如果节点被选中，拦截普通字符输入
                if (from === pos && to === pos + node.nodeSize) {
                  return true;
                }
              }
            }
          }

          return ["keydown", "mousedown", "click", "input", "paste", "copy", "cut"].includes(
            event.type
          );
        },
      };
    };
  },

  renderText({ node }) {
    return `{{${node.attrs.inputValue}}}`;
  },

  onCreate() {
    // eslint-disable-next-line no-console
    console.log("模板变量节点类型初始化完成");
  },
});

// 将 {{变量}} 文本批量转换为 templateVariable 节点
export const convertTemplateVariables = function (editor) {
  if (!editor?.state) return;
  const { state, view } = editor;
  const schema = state.schema;
  const nodeType = schema.nodes["templateVariable"];
  if (!nodeType) {
    // eslint-disable-next-line no-console
    console.error("模板变量节点类型未注册");
    return;
  }
  const regex = /\{\{([^{}]+)\}\}/g;
  const { tr } = state;
  let hasChanges = false;
  const variables: { start: number; end: number; inputValue: string; placeholder: string }[] = [];
  state.doc.descendants((node, pos) => {
    if (!node.isText || !node.text || !node.text.includes("{{")) return true;
    let match;
    while ((match = regex.exec(node.text)) !== null) {
      const [fullMatch, content] = match;
      variables.push({
        start: pos + match.index,
        end: pos + match.index + fullMatch.length,
        inputValue: '',
        placeholder: content.trim(),
      });
    }
    return true;
  });
  variables
    .sort((a, b) => b.start - a.start)
    .forEach(({ start, end, inputValue, placeholder }) => {
      try {
        const node = nodeType.create({ inputValue, placeholder });

        tr.replaceWith(start, end, node);
        hasChanges = true;
      } catch (error) {
        // eslint-disable-next-line no-console
        console.error(`转换模板变量失败: ${inputValue}`, error);
      }
    });
  if (hasChanges) {
    view.dispatch(tr);
    // eslint-disable-next-line no-console
    console.log(`转换了${variables.length}个模板变量`);
  }
};

/*
=== 模板变量节点 (TemplateVariable) 功能说明 ===

## 核心功能
1. 将文本中的 {{变量}} 格式转换为可编辑的 input 节点
2. 支持内联编辑，自动调整宽度
3. 提供丰富的键盘导航和节点操作功能

## 节点属性
- inputValue: 变量的实际值
- placeholder: 占位符文本
- defaultValue: 默认显示值（用于节点分割等场景）

## 键盘快捷键
### Shift + Enter (节点分割/复制)
- 空节点：复制当前节点到下一行
- 非空节点：根据光标位置分割节点
  * 光标在开头：在前面插入空节点
  * 光标在中间：分割为两个节点
  * 光标在末尾：在后面插入空节点

### 方向键导航
- 左右键：在 input 边界时移出节点
- 上下键：移动到上下行对应位置
- 移入节点时自动聚焦到 input
- 根据移入方向设置光标位置（左移入→开头，右移入→末尾）

### Backspace/Delete
- 在 input 边界时删除相邻文本或移动光标

## 自动行为
1. 宽度自适应：根据内容或占位符自动调整 input 宽度
2. 自动聚焦：节点被选中时自动聚焦到 input
3. 智能光标定位：根据移入方向自动设置光标位置

## 样式特性
- 透明背景，无边框
- 编辑时添加 editing-template-var 类
- 内容居中对齐，空内容左对齐
- 最小宽度 60px，自动扩展

## 使用示例
```javascript
// 1. 转换文本中的模板变量
convertTemplateVariables(editor);

// 2. 手动插入模板变量节点
editor.chain().focus().insertContent({
  type: "templateVariable",
  attrs: {
    inputValue: "变量内容",
    placeholder: "请输入变量"
  }
}).run();

// 3. 获取所有模板变量的值
editor.state.doc.descendants((node) => {
  if (node.type.name === "templateVariable") {
    console.log("变量值:", node.attrs.inputValue);
  }
});

// 4. 使用 nodeType.create 创建节点
const nodeType = editor.state.schema.nodes.templateVariable;
const newNode = nodeType.create({
  inputValue: "新变量",
  placeholder: "输入内容"
});
```

## ProseMirror 节点创建 API
### nodeType.create(attrs, content?, marks?)
- **nodeType**: ProseMirror schema 中的 NodeType 实例（如 templateVariable 节点类型）
- **attrs**: 节点的属性对象（必需）
  * inputValue: 变量的实际值
  * placeholder: 占位符文本
  * defaultValue: 默认显示值
- **content**: 子内容（可选，本节点通常为空）
- **marks**: 节点的 marks（可选，如加粗、斜体等）
- **返回值**: Node 实例，可用于插入到文档树中

### 节点创建示例
```javascript
// 基本创建
const node = nodeType.create({
  inputValue: "变量内容",
  placeholder: "请输入"
});

// 带默认值创建（用于节点分割）
const nodeWithDefault = nodeType.create({
  inputValue: "",
  placeholder: "变量名",
  defaultValue: "分割后的内容"
});
```

## 技术实现要点
1. 使用 atom: true 确保节点不可分割
2. 自定义 NodeView 实现 input 渲染
3. 全局键盘事件监听处理节点间导航
4. 事务 (Transaction) 管理确保状态同步
5. DOM 操作与 ProseMirror 状态的双向绑定

## 注意事项
- 节点创建后需要调用 adjustWidth() 确保正确显示
- 编辑状态 (isEditing) 用于避免更新冲突
- 事件监听器需要在 destroy() 中正确清理
- 使用 setTimeout 确保 DOM 更新后再执行操作
- nodeType.create 创建的节点需要通过事务插入到文档中
*/

export default TemplateVariable;
